﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace MikeSoft.Tool.Common
{

    public static class SymmetricAlgorithmCrypto
    {
        #region 对称加密算法
        //加密/解密密码
        static string pwd = "123456";
        //缓冲区大小
        static int bufferSize = 128 * 1024;
        //密钥salt
        static byte[] salt = { 134, 216, 7, 36, 88, 164, 91, 227, 174, 76, 191, 197, 192, 154, 200, 248 };
        //初始化向量
        static byte[] iv = { 134, 216, 7, 36, 88, 164, 91, 227, 174, 76, 191, 197, 192, 154, 200, 248 };
        /// <summary>
        /// 初始化并返回对称加码算法
        /// </summary>
        /// <param name="pwd"></param>
        /// <param name="salt"></param>
        /// <returns></returns>
        public static SymmetricAlgorithm CreatRijndael(byte[] salt)
        {
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt, "SHA256", 1000);
            SymmetricAlgorithm sma = Rijndael.Create();
            sma.KeySize = 256;
            sma.Key = pdb.GetBytes(32);
            sma.Padding = PaddingMode.PKCS7;
            return sma;
        }
        /// <summary>
        /// 加密文件
        /// </summary>
        /// <param name="inFile"></param>
        /// <param name="outFile"></param>
        /// <param name="pwd"></param>
        public static void EncryptFile(string inFile, string outFile)
        {
            using (FileStream inFS = File.OpenRead(inFile), outFS = File.Open(outFile, FileMode.OpenOrCreate))
            {
                using (SymmetricAlgorithm sa = CreatRijndael(salt))
                {
                    sa.IV = iv;
                    using (CryptoStream outCS = new CryptoStream(outFS, sa.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        byte[] bytes = new byte[bufferSize];
                        int readSize = -1;
                        while ((readSize = inFS.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            outCS.Write(bytes, 0, readSize);
                        }
                        outCS.Flush();
                    }
                }
            }
        }
        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inFile"></param>
        /// <param name="outFile"></param>
        /// <param name="pwd"></param>
        public static void DecryptFile(string inFile, string outFile)
        {
            using (FileStream inFS = File.OpenRead(inFile), outFS = File.OpenWrite(outFile))
            {
                using (SymmetricAlgorithm sa = CreatRijndael(salt))
                {
                    sa.IV = iv;
                    using (CryptoStream inCS = new CryptoStream(inFS, sa.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        byte[] bytes = new byte[bufferSize];
                        int readSize = -1;
                        int numReads = (int)(inFS.Length / bufferSize);
                        int slack = (int)(inFS.Length % bufferSize);
                        for (int i = 0; i < numReads; ++i)
                        {
                            readSize = inCS.Read(bytes, 0, bytes.Length);
                            outFS.Write(bytes, 0, readSize);
                        }
                        if (slack > 0)
                        {
                            try
                            {
                                readSize = inCS.Read(bytes, 0, (int)slack);
                                outFS.Write(bytes, 0, readSize);
                            }
                            catch (Exception ex)
                            {

                                throw new Exception("密码错误:", ex);
                            }
                        }
                        outFS.Flush();

                    }
                }
            }
        }
        #endregion
    }
    #region 非对称加密算法
    #endregion
    public static class MD5Crypto
    {
    }

}
